﻿using BusinessDB;
using BusinessResource;
using BusinessService;
using BusinessService.proto;
using DocumentFormat.OpenXml.Spreadsheet;
using Google.ProtocolBuffers;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace LightingTcpService
{
    public class ProdFactory
    {
        private static Dictionary<string, PropertyInfo> _propertyCache;
        private static Dictionary<string, PictureType> _pictureTypes;
        private static IList<ColRef> _colCache;
        private static IList<ColRef> _imgColCache;
        private ResArray _resArray;
        private DirectoryInfo _forder;

        private ResArray ResArray
        {
            get
            {
                if (_resArray == null)
                {
                    OriginalBusiness business = new OriginalBusiness();
                    byte[] bytes = business.GetStaticResource();
                    _resArray = ResArray.ParseFrom(bytes);
                }
                return _resArray;
            }
        }

        static ProdFactory()
        {
            _propertyCache = new Dictionary<string, PropertyInfo>();
            foreach (PropertyInfo pi in typeof(ProdDB).GetProperties())
            {
                _propertyCache[pi.Name] = pi;
            }

            _colCache = new List<ColRef>()
            {
                new ColRef() {  ColName = "产品系列", PropertyName = "ProdSeries", Index=5 },
                new ColRef() {  ColName = "产品分类", PropertyName = "ProdClass", IsRef=true, Guid = 1, Index=6 },
                new ColRef() {  ColName = "使用场所", PropertyName = "ProdPlace", IsRef=true, Guid = 2, Index=7 },
                new ColRef() {  ColName = "规格型号", PropertyName = "ProdVersion", Index=8 },
                new ColRef() {  ColName = "产品品牌", PropertyName = "ProdLabel", Index=9 },
                new ColRef() {  ColName = "产地", PropertyName = "ProdOrgin", IsRef=true, Guid = 3, Index=12 },

                new ColRef() {  ColName = "材质说明", PropertyName = "PhyMaterial", Index=13 },
                new ColRef() {  ColName = "外观颜色", PropertyName = "PhyColor", Index=14 },
                new ColRef() {  ColName = "外形尺寸", PropertyName = "PhySize", Index=15 },
                new ColRef() {  ColName = "防护等级", PropertyName = "PhyDefend", Index=16},
                new ColRef() {  ColName = "防撞击等级", PropertyName = "PhyImpact", IsRef=true, Guid = 4, Index=18 },
                new ColRef() {  ColName = "产品重量", PropertyName = "PhyWeight", Index=19 },

                new ColRef() {  ColName = "配光说明", PropertyName = "OptExplain", IsRef=true, Guid = 5, Index=21 },
                new ColRef() {  ColName = "光束角", PropertyName = "OptEff", Index=22 },
                new ColRef() {  ColName = "灯具效率", PropertyName = "OptAngle", Index=23 },

                new ColRef() {  ColName = "防触电等级", PropertyName = "EleShock", Index=24 },
                new ColRef() {  ColName = "工作电压", PropertyName = "EleVoltage", IsRef=true, Guid = 6, Index=25},
                new ColRef() {  ColName = "电器类型", PropertyName = "EleType", Index=26 },
                new ColRef() {  ColName = "电器功耗", PropertyName = "ElePower", Index=27 },
                new ColRef() {  ColName = "光源功率", PropertyName = "EleLgtPower", Index=28 },
                new ColRef() {  ColName = "整灯功耗", PropertyName = "EleAllPower", Index=29 },
                new ColRef() {  ColName = "控制方式", PropertyName = "EleCtlType", IsRef=true, Guid = 7, Index=31 },

                new ColRef() {  ColName = "光源种类", PropertyName = "AdpClass", IsRef=true, Guid = 8, Index=32 },
                new ColRef() {  ColName = "光源型号", PropertyName = "AdpVersion", Index=34 },
                new ColRef() {  ColName = "色温或颜色", PropertyName = "AdpColor", Index=35 },
                new ColRef() {  ColName = "显色性CRI", PropertyName = "AdpCri", Index=36 },
                new ColRef() {  ColName = "光输出", PropertyName = "AdpOutput", Index=37 },
                new ColRef() {  ColName = "插脚形式", PropertyName = "AdpPins", Index=38 },

                new ColRef() {  ColName = "可选配件", PropertyName = "ProjParts", Index=41 },
                new ColRef() {  ColName = "安装方式", PropertyName = "ProjSetup", IsRef=true, Guid = 9, Index=42},
                new ColRef() {  ColName = "安装尺寸", PropertyName = "ProjSize", Index=43 },
                new ColRef() {  ColName = "认证及检测报告", PropertyName = "ProjReport", Index=48 },
                new ColRef() {  ColName = "备注", PropertyName = "ProjBaikup", Index=49 },

                new ColRef() {  ColName = "参考进价", PropertyName = "BusIn", Index=55 },
                new ColRef() {  ColName = "市场参考价", PropertyName = "BusMarket", Index=56 },
                new ColRef() {  ColName = "参考售价", PropertyName = "BusOut", Index=57 },
                new ColRef() {  ColName = "参考货期", PropertyName = "BusExpires", Index=58 }
            };

            _imgColCache = new List<ColRef>()
            {
                new ColRef() {  Index=59, ColName = "图片(外观)", PropertyName = "PicFacade" },
                new ColRef() {  Index=60, ColName = "图片(尺寸)", PropertyName = "PicSize" },
                new ColRef() {  Index=61, ColName = "图片(配光1)", PropertyName = "PicGrading" },
                new ColRef() {  Index=62, ColName = "图片(实景)", PropertyName = "PicLive" }
            };

            _pictureTypes = new Dictionary<string, PictureType>();
            _pictureTypes["png"] = PictureType.PNG;
            _pictureTypes["bmp"] = PictureType.BMP;
            _pictureTypes["jpg"] = PictureType.JPG;
            _pictureTypes["jpeg"] = PictureType.JPG;
            _pictureTypes["gif"] = PictureType.GIF;
        }

        public IList<ProdDB> Create(byte[] packages)
        {
            string newForder = Path.Combine(ServerConfig.Singleton.ImgRoot, DateTime.Now.ToString("yyyyMMddHHmmss"));
            _forder = Directory.CreateDirectory(newForder);

            WorkbookParser parser = new WorkbookParser(packages);
            WorkbookModel model = parser.Parse();

            SLExcelReader reader = new SLExcelReader();
            SLExcelData excelData = reader.ReadExcel(model.ExcelFile.Stream);

            List<ProdDB> list = new List<ProdDB>();
            int index = 0;
            foreach (List<string> data in excelData.DataRows)
            {
                index++;
                ProdDB prodDB = Create(data, string.Format("{0}|{1}|", excelData.SheetName, index + 2), model);
                if(prodDB != null)
                    list.Add(prodDB);
            }
            return list;
        }

        private byte[] BmpToPNG(byte[] stream)
        {
            Image img = Image.FromStream(new MemoryStream(stream));
            byte[] arr = null;
            using (MemoryStream ms = new MemoryStream())
            {
                img.Save(ms, ImageFormat.Png);
                arr = ms.ToArray();
            }

            return arr;
        }

        private ResItem GetResItem(int guid, string itemName)
        {
            return (from r in ResArray.ResList
                    where r.Id == guid && r.ItemName == itemName
                    select r).FirstOrDefault();
        }

        private ProdDB Create(IList<string> data, string prefixKey, IImageProvider provider)
        {
            ProdDB instance = (ProdDB)Activator.CreateInstance(typeof(ProdDB));

            foreach (ColRef colRef in _colCache)
            {
                try
                {
                    string value = data[colRef.Index];
                    if (string.IsNullOrEmpty(value))
                        continue;

                    PropertyInfo pi = _propertyCache[colRef.PropertyName];
                    if (colRef.IsRef)
                    {
                        ResItem resItem = GetResItem(colRef.Guid, value);
                        pi.SetValue(instance, resItem.ItemID, null);
                    }
                    else
                    {

                        if (pi.PropertyType == typeof(string))
                        {
                            pi.SetValue(instance, value, null);
                        }
                        else if (pi.PropertyType == typeof(int))
                        {
                            int intValue;
                            if (int.TryParse(value, out intValue))
                                pi.SetValue(instance, intValue, null);
                        }
                        else if (pi.PropertyType == typeof(double))
                        {
                            double doubleValue;
                            if (double.TryParse(value, out doubleValue))
                                pi.SetValue(instance, doubleValue, null);
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }

            if (instance.ProdClass == 0)
                return null;

            foreach (ColRef colRef in _imgColCache)
            {
                try
                {
                    ImageFile imageFile = provider.GetImageFileByKey(string.Format("{0}{1}", prefixKey, colRef.Index + 1));
                    if (imageFile != null)
                    {
                        int extStartIndex = imageFile.Name.LastIndexOf('.');
                        string ext = imageFile.Name.Substring(extStartIndex + 1).ToLower();
                        string prefixName = imageFile.Name.Substring(0, extStartIndex);

                        string localName = imageFile.Name;
                        if (ext == "bmp")
                        {
                            using (MemoryStream ms = new MemoryStream(imageFile.File))
                            {
                                Image bmpImage = Image.FromStream(ms);
                                localName = prefixName + ".jpg";
                                bmpImage.Save(Path.Combine(_forder.FullName, localName), ImageFormat.Jpeg);
                            }
                        }
                        else
                        {
                            using (FileStream fs = File.Create(Path.Combine(_forder.FullName, localName)))
                            {
                                fs.Write(imageFile.File, 0, imageFile.File.Length);
                                fs.Flush();
                            }
                        }

                        PropertyInfo pi = _propertyCache[colRef.PropertyName];
                        pi.SetValue(instance, _forder.Name + "/" + localName, null);
                    }
                }
                catch (Exception ex)
                {
                }
            }

            return (ProdDB)instance;
        }
    }

    public enum PictureType
    {
        PNG = 1,
        BMP = 2,
        JPG = 3,
        GIF = 4
    }
}
